﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Xps.Packaging;

namespace CloudStorageLight.DesktopTool
{
    public abstract class DocumentImageConverter
    {

        public int ThumbnailImageHeight { get; set; }
        public int ThumbnailImageWidth { get; set; }


        public int PreviewImageHeight { get; set; }
        public int PreviewImageWidth { get; set; }


        public List<string> ToImageFile(string inputFile, string outputPatternFile, int pageSize)
        {
            var xpsfile = GetExtnsionFilename(outputPatternFile, "xps");
            var thumbnailfile = GetExtnsionFilename(outputPatternFile, "thmub.jpg");
            var imgfile = GetExtnsionFilename(outputPatternFile, "jpg");

            if (!ToXpsFile(inputFile, xpsfile, pageSize)) return null;
            return ConvertXpsPageToBitmap(xpsfile, imgfile, pageSize, "jpg", 1.0);
        }

        public List<string> ToText(string inputFile,  string outputFolder, int pageSize)
        {
            var xpsFile = Path.Combine(outputFolder, "tmp.xps");
            if (!ToXpsFile(inputFile, xpsFile, pageSize)) return null;
            return ConvertXpsToText(xpsFile, pageSize);
        }

        public abstract bool ToXpsFile(string inputFile, string outputFile, int pageSize);

        

        //public string GetThumbnailFilename(string path, string filetype)
        //{
        //    return path + ".thumb." + filetype;
        //}
        //public string GetPreviewFilename(string path, int no, string filetype)
        //{
        //    return path + "."+ no.ToString("000") +"." + filetype;
        //}
        public string GetExtnsionFilename(string path, string filetype)
        {
            return Path.GetDirectoryName(path) + "\\" + Path.GetFileNameWithoutExtension(path) + "." + filetype;
        }


        protected List<string> ConvertXpsPageToBitmap(string xpsFileName, string outputPatternFile, int maxPageSize, string extension, double sizeRate)
        {
            List<string> fileNames = new List<string>();

            using (XpsDocument xpsDoc = new XpsDocument(xpsFileName, FileAccess.Read))
            {
                FixedDocumentSequence docSeq = xpsDoc.GetFixedDocumentSequence();
                if (maxPageSize <= 0)
                {
                    maxPageSize = docSeq.DocumentPaginator.PageCount;
                }
                else
                {
                    maxPageSize = Math.Min(maxPageSize, docSeq.DocumentPaginator.PageCount);
                }
                for (int pageNum = 0; pageNum < maxPageSize; pageNum++)
                {
                    using (DocumentPage docPage = docSeq.DocumentPaginator.GetPage(pageNum))
                    {
                        RenderTargetBitmap renderTarget =
                            new RenderTargetBitmap((int)(docPage.Size.Width * sizeRate),
                                                    (int)(docPage.Size.Height * sizeRate),
                                                    96 * sizeRate,
                                                    96 * sizeRate,
                                                    PixelFormats.Default);
                        renderTarget.Render(docPage.Visual);
                        BitmapEncoder encoder;
                        switch (extension)
                        {
                            case "png": encoder = new PngBitmapEncoder(); break;
                            case "jpg": encoder = new JpegBitmapEncoder(); break;
                            case "tiff": encoder = new TiffBitmapEncoder(); break;
                            case "gif": encoder = new GifBitmapEncoder(); break;
                            case "bmp": encoder = new BmpBitmapEncoder(); break;
                            case "wdp": encoder = new WmpBitmapEncoder(); break;
                            default: extension = "png"; encoder = new PngBitmapEncoder(); break;
                        }

                        string fileName = Path.GetDirectoryName(outputPatternFile) + "\\" + Path.GetFileNameWithoutExtension(outputPatternFile) + "_P" + pageNum.ToString("0000")  + Path.GetExtension(outputPatternFile);
                        fileNames.Add(fileName);
                        encoder.Frames.Add(BitmapFrame.Create(renderTarget));
                        using (FileStream pageOutStream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                        {
                            encoder.Save(pageOutStream);
                            pageOutStream.Close();
                        }

                    }
                }
                xpsDoc.Close();

                return fileNames;
            }
        }


        protected List<string> ConvertXpsToText(string xpsFileName, int maxPageSize)
        {
            var  textContents= new List<string>();
            using (XpsDocument _xpsDocument = new XpsDocument(xpsFileName, FileAccess.Read))
            {
                 FixedDocumentSequence docSeq = _xpsDocument.GetFixedDocumentSequence();
                if (maxPageSize <= 0)
                {
                    maxPageSize = docSeq.DocumentPaginator.PageCount;
                }
                else
                {
                    maxPageSize = Math.Min(maxPageSize, docSeq.DocumentPaginator.PageCount);
                }

                IXpsFixedDocumentSequenceReader fixedDocSeqReader
                    = _xpsDocument.FixedDocumentSequenceReader;
                IXpsFixedDocumentReader _document = fixedDocSeqReader.FixedDocuments[0];
                FixedDocumentSequence sequence = _xpsDocument.GetFixedDocumentSequence();
                for (int pageCount = 0; pageCount < maxPageSize; ++pageCount)
                {
                    IXpsFixedPageReader _page
                        = _document.FixedPages[pageCount];
                    StringBuilder _currentText = new StringBuilder();
                    System.Xml.XmlReader _pageContentReader = _page.XmlReader;
                    if (_pageContentReader != null)
                    {
                        while (_pageContentReader.Read())
                        {
                            if (_pageContentReader.Name == "Glyphs")
                            {
                                if (_pageContentReader.HasAttributes)
                                {
                                    if (_pageContentReader.GetAttribute("UnicodeString") != null)
                                    {
                                        _currentText.
                                            Append(_pageContentReader.
                                            GetAttribute("UnicodeString"));
                                    }
                                }
                            }
                        }
                    }
                    textContents.Add(_currentText.ToString());
                }
            }
            return textContents;
        }
    }
}
